import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Observable, Operator } from "rxjs";
import { BaseUrlService } from "./baseUrl.service";
import { Environment } from "environments/environment";
import { map } from 'rxjs/operators';

import { NavHeaderService } from "@global/layout/default/nav-header/nav-header.service";
const HEADER = new HttpHeaders({
  'Content-Type': 'application/json'
});
const HTTPOPTIONS = {
  headers: HEADER
};

@Injectable({
  providedIn: 'root'
})
export class FcsService {

  constructor(private http: HttpClient,
    private baseUrlService: BaseUrlService,
    private navHeaderService: NavHeaderService) { }

  /**
   * 获取当前请求的后端地址
   * 切换所在区域时 需重新计算
   * @returns
   * @memberof ManageService
   */
  getBaseUrl() {
    let currentRegion = this.navHeaderService.getCurrentRegion();
    return this.baseUrlService.baseUrl(currentRegion);
  }

  getOssBaseUrl() {
    let currentRegion = this.navHeaderService.getCurrentRegion();
    return this.baseUrlService.ossBaseUrl(currentRegion);
  }

  getVPCBaseUrl() {
    let currentRegion = this.navHeaderService.getCurrentRegion();
    return this.baseUrlService.vpcBaseUrl(currentRegion);
  }

  getApigBaseUrl() {
    let currentRegion = this.navHeaderService.getCurrentRegion();
    return this.baseUrlService.apigBaseUrl(currentRegion);
  }

  getCirBaseUrl() {
    let currentRegion = this.navHeaderService.getCurrentRegion();
    return this.baseUrlService.cirBaseUrl(currentRegion);
  }

  createFuction(groupId, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions`;
    return this.http.post(url, data, HTTPOPTIONS).pipe();
  }

  determineFunctionDuplicate(groupId, functionName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/action/exist?functionName=${functionName}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  getFuctionList(groupId, pageNo, pageSize, name): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions?pageNo=${pageNo}&pageSize=${pageSize}&name=${name}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  getAllFunctions(pageNo, pageSize, name): Observable<any> {
    name = encodeURIComponent(name);
    let url = this.getBaseUrl() + `/v1/functions?pageNo=${pageNo}&pageSize=${pageSize}&name=${name}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  getFunctionDetail(groupId, functionId, versionName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/versions/${versionName}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  updateFunction(groupId, functionId, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}`;
    return this.http.put(url, data, HTTPOPTIONS).pipe();
  }

  deleteFunction(groupId, functionId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}`;
    return this.http.delete(url, HTTPOPTIONS).pipe();
  }

  invokeFunction(groupId, functionId, versionName, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/versions/${versionName}/invoke`;
    return this.http.post(url, data, HTTPOPTIONS).pipe();
  }

  /*
  * 获取不使用模板，仅选择运行环境时的默认代码；或者获取使用模板后的代码
  * */
  getDefaultCode(name, runtime): Observable<any> {
    let url = this.getBaseUrl() + `/v1/code/action/download?name=${name}&runtime=${runtime}`;
    let body = null;
    return this.http.post(url, body, HTTPOPTIONS).pipe();
  }

  getCode(groupId, functionId, versionName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/versions/${versionName}/code/download`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  updateCode(groupName, functionName, versionName, code, groupId, functionId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/versions/${versionName}/code/upload`;
    let body = {
      groupName: groupName,
      functionName: functionName,
      versionName: versionName,
      code: code
    };
    return this.http.post(url, body, HTTPOPTIONS).pipe();
  }

  updateOssCode(groupName, functionName, versionName, bucket, object, groupId, functionId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/versions/${versionName}/code/upload`;
    let body = {
      groupName: groupName,
      functionName: functionName,
      versionName: versionName,
      bucket: bucket,
      object: object
    };
    return this.http.post(url, body, HTTPOPTIONS).pipe();
  }

  createTrigger(groupId, functionId, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/triggers`;
    return this.http.post(url, data, HTTPOPTIONS).pipe();
  }

  determineTriggerDuplicate(groupId, functionId, triggerName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/triggers/action/exist?triggerName=${triggerName}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  getTriggerList(groupId, functionId, pageNo, pageSize, name?: string, triggerType?: string): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/triggers`;
    let httpOption = {
      headers: HEADER,
      params: {
        pageNo: pageNo,
        pageSize: pageSize,
        name: (name ? name : ''),
        type: (triggerType ? triggerType : '')
      }
    };
    return this.http.get(url, httpOption).pipe(
        map(response => {
          // 漏洞处理：只返回预定义的字段
          return {
            id: response.id,
            name: response.name,
            // 只包含需要的字段
          };
        })
    );
  }

  getTriggerDetail(groupId, functionId, triggerId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/triggers/${triggerId}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  updateTrigger(groupId, functionId, triggerId, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/triggers/${triggerId}`;
    return this.http.put(url, data, HTTPOPTIONS).pipe();
  }

  deleteTrigger(groupId, functionId, triggerId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/triggers/${triggerId}`;
    return this.http.delete(url, HTTPOPTIONS).pipe();
  }

  createGroup(data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups`;
    return this.http.post(url, data, HTTPOPTIONS).pipe();
  }

  determineGroupDuplicate(groupDisplayName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/action/exist?groupDisplayName=${groupDisplayName}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  getGroupList(): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  getGroupPaginationList(pageNo, pageSize, displayName): Observable<any> {
    displayName = encodeURIComponent(displayName);
    let url = this.getBaseUrl() + `/v1/groups?pageNo=${pageNo}&pageSize=${pageSize}&displayName=${displayName}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  getGroupDetail(groupId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  updateGroup(groupId, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}`;
    return this.http.put(url, data, HTTPOPTIONS).pipe();
  }

  deleteGroup(groupId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}`;
    return this.http.delete(url, HTTPOPTIONS).pipe();
  }

  getLogList(groupId, functionId, pageNo, pageSize, startTime?, endTime?, requestId?, status?): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/logs`;
    let httpOption = {
      headers: HEADER,
      params: {
        pageNo: pageNo,
        pageSize: pageSize
      }
    };
    if (startTime) {
      httpOption.params['startTime'] = startTime;
    }
    if (endTime) {
      httpOption.params['endTime'] = endTime;
    }
    if (requestId) {
      httpOption.params['requestId'] = requestId;
    }
    if (status) {
      httpOption.params['status'] = status;
    }
    return this.http.get(url, httpOption).pipe(
        map(response => {
          // 漏洞处理：只返回预定义的字段
          return {
            id: response.id,
            name: response.name,
            // 只包含需要的字段
          };
        })
    );
  }

  getFunctionMetrics(groupId, functionId, startTime, endTime, period, metricName, version): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/metrics`;
    let httpOption = {
      headers: HEADER,
      params: {
        startTime: startTime,
        endTime: endTime,
        period: period,
        metricName: metricName,
        version: version
      }
    };
    return this.http.get(url, httpOption).pipe();
  }

  getDefaultRegion() {
    const region = Environment.application.defaultRegion || 'cn-north-3';
    return { regionCode: region, regionName: '华北三' };
  }

  getRegionMetrics() {
    let url = this.getBaseUrl() + `/v1/functions/metrics`;
    let httpOption = {
      headers: HEADER,
    };
    return this.http.get(url, httpOption).pipe();
  }

  getFunctionNum() {
    let url = this.getBaseUrl() + `/v1/functions/metrics-functions`;
    let httpOption = {
      headers: HEADER,
    };
    return this.http.get(url, httpOption).pipe();
  }

  getOssBucketList(pageNo, pageSize): Observable<any> {
    let url = this.getOssBaseUrl() + `/v1/buckets/${pageNo}/${pageSize}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  createVersion(groupId, functionId, data?): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/versions`;
    return this.http.post(url, data, HTTPOPTIONS).pipe();
  }

  getVersionList(groupId, functionId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/versions`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  deleteFunctionVersion(groupId, functionId, versionName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/versions/${versionName}`;
    return this.http.delete(url, HTTPOPTIONS).pipe();
  }

  createAlias(groupId, functionId, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/aliases`;
    return this.http.post(url, data, HTTPOPTIONS).pipe();
  }

  functionAlias(groupId, functionId, aliasName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/aliases/${aliasName}/exist`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  deleteFunctionAlias(groupId, functionId, aliasName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/aliases/${aliasName}`;
    return this.http.delete(url, HTTPOPTIONS).pipe();
  }

  getAliasList(groupId, functionId): Observable<any> {
    //v1/groups/{groupId}/functions/{functionId}/aliases
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/aliases`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  updateFunctionAlias(groupId, functionId, aliasName, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/aliases/${aliasName}`;
    return this.http.put(url, data, HTTPOPTIONS).pipe();
  }

  /*获取该用户的所有VPC*/
  getVPCList(regionCode): Observable<any> {
    let url = this.getVPCBaseUrl() + `/v1/vpcs/listall`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  getApigGroupList() {
    let url = this.getApigBaseUrl() + `/apps/v1/groups/1/1000?name=`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  // 获取容器镜像列表
  getCirTagList() {
    let url = this.getCirBaseUrl() + `/images/v1/images/tags`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  /*
  * 获取模板列表
  * */
  getTemplateData(pageNo = 1, pageSize = 1000, name = '', scene = '', runtime = '') {
    // ifcs/v1/templates?pageNo=1&pageSize=6&name=
    let url = this.getBaseUrl() + `/v1/templates?pageNo=${pageNo}&pageSize=${pageSize}&name=${name}&scene=${scene}&runtime=${runtime}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  /**
   * 获取模板的不同场景值
   */
  getTemplateScenes() {
    let url = this.getBaseUrl() + `/v1/template-scenes`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }

  // 自定义域名
  getDomainList(pageNo, pageSize): Observable<any> {
    let url = this.getBaseUrl() + `/v1/domains?pageNo=${pageNo}&pageSize=${pageSize}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }
  getDomainDetail(domainId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/domains/${domainId}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }
  determineDomainDuplicate(domainName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/domains/action/exist?domainName=${domainName}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }
  createDomain(data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/domains`;
    return this.http.post(url, data, HTTPOPTIONS).pipe();
  }
  updateDomain(domainId, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/domains/${domainId}`;
    return this.http.put(url, data, HTTPOPTIONS).pipe();
  }
  deleteDomain(domainId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/domains/${domainId}`;
    return this.http.delete(url, HTTPOPTIONS).pipe();
  }



  // 层
  getLayerList(pageNo, pageSize,searchValue): Observable<any>{
    searchValue = encodeURIComponent(searchValue);
    let url = this.getBaseUrl()  + `/v1/layers?pageNo=${pageNo}&pageSize=${pageSize}&name=${searchValue}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }
  createLayer(data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/layers`;
    return this.http.post(url, data, HTTPOPTIONS).pipe();
  }
  getLayerDetail(layerId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/layers/${layerId}/versions`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }
  getLayerVersion(layerId,data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/layers/${layerId}/versions`;
    return this.http.post(url,data, HTTPOPTIONS).pipe();
  }
  deleteVersion(layerId,versionName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/layers/${layerId}/versions/${versionName}`;
    return this.http.delete(url, HTTPOPTIONS).pipe();
  }
  downLoadCode(layerId,versionName): Observable<any>{
    let url = this.getBaseUrl() + `/v1/layers/${layerId}/versions/${versionName}/code/download`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }
  getLayerExist(layerName): Observable<any> {
    let url = this.getBaseUrl() + `/v1/layers/action/exist?layerName=${layerName}`;
    return this.http.get(url, HTTPOPTIONS).pipe();
  }
  // 上传层代码
	uploadCode(data,layerId): Observable<any> {
    let url = this.getBaseUrl() + `/v1/layers/${layerId}/code/upload`;
    return this.http.post(url, data, HTTPOPTIONS).pipe();
  }
	// 修改函数层（解绑 绑定层）
	modifyFunctionLayer(groupId, functionId, data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/layer`;
    return this.http.put(url, data, HTTPOPTIONS).pipe();
  }
	// 获取某运行环境的层
	getLayerByRuntime(data): Observable<any> {
    let url = this.getBaseUrl() + `/v1/compatible-layers?runtime=${data}`;
    return this.http.get(url, data).pipe();
  }



  copyFunction(groupId,functionId,body): Observable<any>{
    let url = this.getBaseUrl() + `/v1/groups/${groupId}/functions/${functionId}/action/copy`;
    return this.http.post(url, body,HTTPOPTIONS).pipe();
  }
}
